ホームに戻る
関連 :
目次 :
コントロールの操作に関する制約
WPFでは、Windows Formsと同様にコントロールに対する操作はUIスレッドから行う必要がある。
UIスレッドには、各ウィンドウに関連付けられたイベントハンドラが該当する。
即ち原則として、コントロールの操作はイベントハンドラ(と同一のスレッド)からでなければ実行することができない。

別スレッド(ワーカースレッド)からコントロールの操作を行う場合、UIスレッドに処理を委譲する必要がある。
尚、Windows Formsと異なり、InvokeRequired プロパティは存在しない。
処理の委譲先
- 操作対象が自身のWindow : Window.Dispatcher
- 操作対象が自身ではない(自身に対しても使用可) : Application.Current.Dispatcher
いずれも Invoke() メソッドに行いたい処理を引数として渡す。
ワーカースレッドからのコントロール操作
(ウィンドウ : HogeWindow.cs)
class HogeWindow : Window
{
// ContentRendered イベントハンドラ
private void Window_ContentRendered(object sender, EventArgs e)
{
// 別スレッド(ワーカースレッド)にて処理を実行
Task t = Task.Run( () => DoSomething() );
}
// UIスレッド外で行われる処理
private void DoSomething()
{
// ラベルの表記を更新
UpdateLabel("テスト");
}
// ラベルの表記を更新
// (UIスレッド外で行われる処理)
private void UpdateLabel(string msg)
{
Dispatcher.Invoke( () => SomeLabel.Content = msg );
}
}
ワーカースレッドからのウィンドウ開閉
(ウィンドウ : HogeWindow.cs)
class HogeWindow : Window
{
// ContentRendered イベントハンドラ
private void Window_ContentRendered(object sender, EventArgs e)
{
// 別スレッド(ワーカースレッド)にて処理を実行
Task t = Task.Run( () => DoSomething() );
}
// UIスレッド外で行われる処理
private void DoSomething()
{
try
{
// 別の Window を開く
// ⇒ UIスレッドに委譲
Application.Current.Dispatcher.Invoke( () => ( new MainWindow() ).Show() );
}
// 例外発生時
catch ( Exception ex )
{
:
}
finally
{
// 自身のウィンドウを閉じる
// ⇒ UIスレッドに委譲
Application.Current.Dispatcher.Invoke( () => Close() );
}
}
}
Invoke() に関する制約
Invoke() に渡すことのできるデリゲートは Action 型(戻り値の無いメソッド)に限定される。